package com.ncmmall.mall.controller.business.advertis;

import com.ncmmall.application.business.advertis.AdvertisApplication;
import com.ncmmall.application.securitys.logs.OperationLogApplication;
import com.feijin.commons.webs.Webs;
import com.ncmmall.domain.business.advertis.Advertis;
import com.ncmmall.domain.business.advertis.QAdvertis;
import com.ncmmall.domain.business.goods.Goods;
import com.ncmmall.domain.business.goods.channel.GoodsChannel;
import com.ncmmall.domain.business.goods.channel.QGoodsChannel;
import com.ncmmall.domain.business.subject.SubjectActivity;
import com.ncmmall.domain.security.user.QWebUser;
import com.ncmmall.domain.security.user.WebUser;
import com.ncmmall.mall.controller.securitys.shiro.Securitys;
import com.ncmmall.mall.params.PageParams;
import com.ncmmall.querychannel.QueryPage;
import com.ncmmall.querychannel.QueryPageRequest;
import com.ncmmall.querychannel.service.QueryChannelService;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 广告
 *
 * @author likaikai
 * @date 2019-07-11 19:44
 */
@Controller
@RequestMapping("/mall/advertis")
@Slf4j
public class AdvertisController {

    @Autowired
    private AdvertisApplication advertisApplication;

    @Autowired
    private QueryChannelService queryChannelService;

    @Autowired
    private OperationLogApplication logApplication;

    /**
     * 广告列表
     */
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    public String list(Model model, Advertis params) {

        Map<String, Object> map = new HashMap<>(3);

        String sql = buildSql("select * from mall_advertis where 1 = 1", map, params);

        List<Advertis> page = queryChannelService.queryAllEntity(sql, map, Advertis.class);

        model.addAttribute("page", page);
        model.addAttribute("params", params);

        return "mall/advertis/list";
    }

    /**
     * 选择商品页面
     */
    @RequestMapping(value = "/chooseGoods", method = RequestMethod.GET)
    public String choose(Model model, PageParams pageParams, Goods goods) {

        QueryPageRequest pageRequest = new QueryPageRequest().setPageNo(pageParams.getPageNo());
        Map<String, Object> params = Maps.newHashMap();
        String hql = builderSQL("select u from Goods u where 1=1  ", params, goods);
        QueryPage<Goods> page = queryChannelService.findPage(hql, pageRequest.setParams(params), Goods.class);
        List<WebUser> merchants;
        if (goods.getIsSupplier() == 1) {
            merchants = queryChannelService.findAll(QWebUser.webUser.role.name.eq("SUPPLIER"), WebUser.class);
        } else {
            merchants = queryChannelService.findAll(QWebUser.webUser.role.name.eq("MERCHANT"), WebUser.class);
        }

        model.addAttribute("page", page)
                .addAttribute("params", goods)
                .addAttribute("merchants", merchants)
                .addAttribute("channels", queryChannelService.findAll("select c from GoodsChannel c where c.deleteStatus = 0 and  c.level = 1 and c.status = 1 ", GoodsChannel.class));

        return "mall/goods/choose";
    }


    /**
     * 选择专题页面
     */
    @RequestMapping(value = "/chooseSubject", method = RequestMethod.GET)
    public String chooseSubject(Model model, PageParams pageParams, SubjectActivity params) {

        QueryPageRequest pageRequest = new QueryPageRequest().setPageNo(pageParams.getPageNo()).setPageSize(pageParams.getPageSize());
        String hql = "select t from SubjectActivity t where t.status = 2";
        Map<String, Object> map = new HashMap<>();

        if (StringUtils.isNotBlank(params.getName())) {
            hql += " and t.name like :name";
            map.put("name", "%" + params.getName() + "%");
        }

        if (StringUtils.isNotBlank(params.getDescription())) {
            hql += " and t.description like :description";
            map.put("description", "%" + params.getDescription() + "%");
        }

        hql += " order by t.createTime desc";

        QueryPage<SubjectActivity> page = queryChannelService.findPage(hql, pageRequest.setParams(map), SubjectActivity.class);

        model.addAttribute("page", page);
        model.addAttribute("params", params);

        return "mall/goods/chooseSubject";
    }


    /**
     * 选择商品类目
     */
    @RequestMapping(value = "/chooseChannel", method = RequestMethod.GET)
    public String chooseChannel(Model model, PageParams pageParams, Goods goods) {

        QueryPageRequest pageRequest = new QueryPageRequest().setPageNo(pageParams.getPageNo());
        Map<String, Object> params = Maps.newHashMap();

        String hql = "select c from GoodsChannel c where c.deleteStatus = 0 and c.status = 1";

        if (null != goods.getGoodsChannel() && goods.getGoodsChannel().getId() > 0) {
            hql += " and c.id = :cid ";
            params.put("cid", goods.getGoodsChannel().getId());
        } else if (null != goods.getGoodsChannel() && goods.getGoodsChannel().getParent() != null && goods.getGoodsChannel().getParent().getId() > 0) {
            hql += " and c.parent.id = :cid ";
            params.put("cid", goods.getGoodsChannel().getParent().getId());
        } else if (null != goods.getGoodsChannel() && goods.getGoodsChannel().getParent() != null && goods.getGoodsChannel().getParent().getParent() != null && goods.getGoodsChannel().getParent().getParent().getId() > 0) {
            hql += " and (c.parent.id = :cid or c.parent.parent.id = :cid)  ";
            params.put("cid", goods.getGoodsChannel().getParent().getParent().getId());
        }

        QueryPage<GoodsChannel> page = queryChannelService.findPage(hql, pageRequest.setParams(params), GoodsChannel.class);


        model.addAttribute("page", page)
                .addAttribute("params", goods)
                .addAttribute("channels", queryChannelService.findAll("select c from GoodsChannel c where c.deleteStatus = 0 and  c.level = 1 and c.status = 1 ", GoodsChannel.class));

        return "mall/goods/chooseChannel";
    }


    /**
     * 条件筛选
     */
    private String builderSQL(String sql, Map<String, Object> params, Goods goods) {

        if (goods.getIsSupplier() > 0) {
            sql += " and u.isSupplier = 1 ";
        } else {
            sql += " and u.isSupplier = 0 ";
        }

        if (null != goods.getGoodsChannel() && goods.getGoodsChannel().getId() > 0) {
            goods.setGoodsChannel(queryChannelService.findOne(QGoodsChannel.goodsChannel.id.eq(goods.getGoodsChannel().getId()), GoodsChannel.class));

            sql += " and u.goodsChannel.id = :cid ";
            params.put("cid", goods.getGoodsChannel().getId());

        } else if (null != goods.getGoodsChannel() && goods.getGoodsChannel().getParent().getId() > 0) {
            goods.getGoodsChannel().setParent(queryChannelService.findOne(QGoodsChannel.goodsChannel.id.eq(goods.getGoodsChannel().getParent().getId()), GoodsChannel.class));

            sql += " and u.goodsChannel.parent.id = :cid ";
            params.put("cid", goods.getGoodsChannel().getParent().getId());

        } else if (null != goods.getGoodsChannel() && goods.getGoodsChannel().getParent().getParent().getId() > 0) {
            goods.getGoodsChannel().getParent().setParent(queryChannelService.findOne(QGoodsChannel.goodsChannel.id.eq(goods.getGoodsChannel().getParent().getParent().getId()), GoodsChannel.class));

            sql += " and u.goodsChannel.parent.parent.id = :cid ";
            params.put("cid", goods.getGoodsChannel().getParent().getParent().getId());
        }

        if (goods.getMerchant() != null && goods.getMerchant().getId() > 0) {
            sql += " and u.merchant.id = :merchantId ";
            params.put("merchantId", goods.getMerchant().getId());
        }

        if (goods.getStatus() > 0) {
            sql += " and u.status = :status ";
            params.put("status", goods.getStatus());
        } else {
            sql += " and u.status in (3,6) ";
        }

        if (!Strings.isNullOrEmpty(goods.getGoodsNo())) {
            sql += " and u.goodsNo like :goodsno ";
            params.put("goodsno", "%" + goods.getGoodsNo() + "%");
        }

        if (!Strings.isNullOrEmpty(goods.getName())) {
            sql += " and u.name like :name ";
            params.put("name", "%" + goods.getName() + "%");
        }


        if (!Strings.isNullOrEmpty(goods.getOrderByCreateTime())) {
            sql += " order by u.createTime " + goods.getOrderByCreateTime();
        } else if (!Strings.isNullOrEmpty(goods.getOrderByPrice())) {
            sql += " order by u.defaultPrice " + goods.getOrderByPrice();
        } else if (!Strings.isNullOrEmpty(goods.getOrderByStore())) {
            sql += " order by u.store " + goods.getOrderByStore();
        } else if (!Strings.isNullOrEmpty(goods.getOrderBySalesVolume())) {
            sql += " order by u.salesVolume " + goods.getOrderBySalesVolume();
        } else {
            sql += " order by u.createTime desc ";
        }

        return sql;
    }

    /**
     * 条件查询
     */
    private String buildSql(String sql, Map<String, Object> map, Advertis params) {

        if (params.getPosition() > 0) {
            sql += " and position = :position";
            map.put("position", params.getPosition());
        }

        if (StringUtils.isNotBlank(params.getName())) {
            sql += " and name like :name";
            map.put("name", "%" + params.getName() + "%");
        }

        if (params.getStatus() > 0) {
            sql += " and status = :status";
            map.put("status", params.getStatus());
        }

        sql += " order by rank asc, createTime desc";

        return sql;
    }


    /**
     * 创建广告
     */
    @RequestMapping(value = "/create", method = RequestMethod.GET)
    public String create(Model model) {
        model.addAttribute("_method", "POST");
        model.addAttribute("advertis", new Advertis());
        return "mall/advertis/form";
    }


    /**
     * 创建广告
     */
    @RequestMapping(value = "/create", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> create(HttpServletRequest request, @RequestHeader("X-Requested-With") String requestWith, Advertis advertis) {
        try {
            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalArgumentException("request must be ajax");
            }

            advertisApplication.create(advertis);
            logApplication.eventOfSystem(Securitys.currentUser(), "添加广告", Securitys.getIp(request));
            return ImmutableMap.of("status", true, "message", "创建成功");

        } catch (IllegalArgumentException e) {
            return ImmutableMap.of("status", false, "message", e.getMessage());
        } catch (Exception e) {
            log.error("广告创建异常", e);
            return ImmutableMap.of("status", false, "message", "创建异常");
        }
    }


    /**
     * 编辑广告
     */
    @RequestMapping(value = "/modify", method = RequestMethod.GET)
    public String create(Model model, long id) {
        Advertis advertis = queryChannelService.findOne(QAdvertis.advertis.id.eq(id), Advertis.class);
        model.addAttribute("advertis", advertis);
        model.addAttribute("_method", "PUT");
        return "mall/advertis/form";
    }


    /**
     * 编辑广告
     */
    @RequestMapping(value = "/modify", method = RequestMethod.PUT)
    @ResponseBody
    public Map<String, Object> modify(HttpServletRequest request, @RequestHeader("X-Requested-With") String requestWith, Advertis advertis) {
        try {
            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalArgumentException("request must be ajax");
            }

            advertisApplication.modify(advertis);
            logApplication.eventOfSystem(Securitys.currentUser(), "修改广告", Securitys.getIp(request));

            return ImmutableMap.of("status", true, "message", "编辑成功");

        } catch (IllegalArgumentException e) {

            return ImmutableMap.of("status", false, "message", e.getMessage());

        } catch (Exception e) {

            log.error("广告编辑异常", e);
            return ImmutableMap.of("status", false, "message", "编辑异常");

        }
    }

    /**
     * 下架广告
     */
    @RequestMapping(value = "/disable", method = RequestMethod.PUT)
    @ResponseBody
    public Map<String, Object> disable(HttpServletRequest request, @RequestHeader("X-Requested-With") String requestWith, Advertis advertis) {
        try {
            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalArgumentException("request must be ajax");
            }

            advertisApplication.disable(advertis.getId());

            logApplication.eventOfSystem(Securitys.currentUser(), "下架广告", Securitys.getIp(request));
            return ImmutableMap.of("status", true, "message", "下架成功");

        } catch (Exception e) {

            log.error("广告下架异常", e);
            return ImmutableMap.of("status", false, "message", "下架异常");

        }
    }

    /**
     * 批量下架广告
     */
    @RequestMapping(value = "/disables", method = RequestMethod.PUT)
    @ResponseBody
    public Map<String, Object> disables(HttpServletRequest request, @RequestHeader("X-Requested-With") String requestWith, String data) {
        try {
            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalArgumentException("request must be ajax");
            }

            advertisApplication.disables(data);
            logApplication.eventOfSystem(Securitys.currentUser(), "批量修改广告", Securitys.getIp(request));
            return ImmutableMap.of("status", true, "message", "下架成功");

        } catch (Exception e) {

            log.error("广告批量下架异常", e);
            return ImmutableMap.of("status", false, "message", "下架异常");

        }
    }


    /**
     * 上架广告
     */
    @RequestMapping(value = "/enable", method = RequestMethod.PUT)
    @ResponseBody
    public Map<String, Object> enable(HttpServletRequest request, @RequestHeader("X-Requested-With") String requestWith, Advertis advertis) {
        try {
            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalArgumentException("request must be ajax");
            }
            advertisApplication.enabled(advertis.getId());
            logApplication.eventOfSystem(Securitys.currentUser(), "商家广告", Securitys.getIp(request));
            return ImmutableMap.of("status", true, "message", "上架成功");
        } catch (IllegalArgumentException e) {
            return ImmutableMap.of("status", false, "message", e.getMessage());
        } catch (Exception e) {
            log.error("广告上架异常", e);
            return ImmutableMap.of("status", false, "message", "上架异常");
        }
    }


    /**
     * 批量上架广告
     */
    @RequestMapping(value = "/enables", method = RequestMethod.PUT)
    @ResponseBody
    public Map<String, Object> enables(HttpServletRequest request, @RequestHeader("X-Requested-With") String requestWith, String data) {
        try {
            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalArgumentException("request must be ajax");
            }

            advertisApplication.enables(data);
            logApplication.eventOfSystem(Securitys.currentUser(), "批量上架广告", Securitys.getIp(request));
            return ImmutableMap.of("status", true, "message", "上架成功");

        } catch (Exception e) {

            log.error("广告批量上架异常", e);
            return ImmutableMap.of("status", false, "message", "上架异常");

        }
    }

    /**
     * 删除广告
     */
    @RequestMapping(value = "/remove", method = RequestMethod.DELETE)
    @ResponseBody
    public Map<String, Object> remove(HttpServletRequest request, @RequestHeader("X-Requested-With") String requestWith, Advertis advertis) {
        try {
            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalArgumentException("request must be ajax");
            }

            advertisApplication.remove(advertis.getId());
            logApplication.eventOfSystem(Securitys.currentUser(), "删除广告", Securitys.getIp(request));
            return ImmutableMap.of("status", true, "message", "删除成功");

        } catch (Exception e) {

            log.error("广告删除异常", e);
            return ImmutableMap.of("status", false, "message", "删除异常");

        }
    }
}
